import express from 'express'
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { createServer } from 'vite'

const isTest = process.env.VITEST
const root = process.cwd()
const isProd = process.env.NODE_ENV === 'production'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const resolve = (p) => path.resolve(__dirname, p)
//const indexProd = isProd ? fs.readFileSync(resolve('dist/client/index.html'), 'utf8') : ''
const manifest = isProd ? JSON.parse(fs.readFileSync(resolve('dist/client/.vite/ssr-manifest.json'), 'utf8')) : {}

export const createDev = async () => {
    const app = express()

    const vite = await createServer({
        base: '/',
        root,
        logLevel: 'error',
        server: {
            middlewareMode: true,
            watch: {
                // During tests we edit the files too fast and sometimes chokidar
                // misses change events, so enforce polling for consistency
                usePolling: true,
                interval: 100,
            },
            hmr: {
                port: 5200,
            },
        },
        appType: 'custom',
    })
    app.use(vite.middlewares)

    app.use('*', async (req, res) => {
        try {
            const url = req.originalUrl.replace('/', '/')
            let template, render
            // always read fresh template in dev
            template = fs.readFileSync(resolve('index.html'), 'utf8')
            template = await vite.transformIndexHtml(url, template)
            const entryServer = await vite.ssrLoadModule('/src/entry-server.ts')
            render = entryServer.render
            const [appHtml, preloadLinks] = await render(url, manifest)
            const html = template.replace(`<!--preload-links-->`, preloadLinks).replace(`<!--app-html-->`, appHtml)
            res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
        } catch (error) {
            // eslint-disable-next-line @typescript-eslint/no-unused-expressions
            vite && vite.ssrFixStacktrace(error)
            console.log(error.stack)
            res.status(500).end(error.stack)
        }
    })

    return { app }
}

// const createProd = async () => {
//   const app = express()
//   const compression = await import('compression')
//   app.use(compression.default())
//   const serveStatic = await import('serve-static')
//   app.use(
//     '/test/',
//     serveStatic.default(resolve('dist/client'), {
//       index: false,
//     })
//   )
//   app.use('*', async (req, res) => {
//     try {
//       const url = req.originalUrl.replace('/test/', '/')

//       let template, render

//       if (isProd) {
//         template = indexProd
//         const distEntryServer = await import('./dist/server/entry-server.js')
//         // @ts-ignore
//         render = distEntryServer.render
//       }
//       const [appHtml, preloadLinks] = await render(url, manifest)
//       const html = template.replace(`<!--preload-links-->`, preloadLinks).replace(`<!--app-html-->`, appHtml)
//       res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
//     } catch (error) {
//       // eslint-disable-next-line @typescript-eslint/no-unused-expressions
//       vite && vite.ssrFixStacktrace(error)
//       console.log(error.stack)
//       res.status(500).end(error.stack)
//     }
//   })
// }

if (!isTest) {
    createDev().then(({ app }) =>
        app.listen(5300, () => {
            console.log('http://localhost:5300')
        })
    )
}
